home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-01-26 | 2.6 KB | 61 lines | [TEXT/CCL2] |
- ;;; Make backup versions of files
-
- (defparameter *backup-files* t)
- (defparameter *too-many-versions* 6)
-
- ;;; This makes a pseudo-versioned copy of a file.
- (defun backup-file (file &key (rename-old-file nil) (query-for-reap t))
- (when (probe-file file) ; if file doesn't exist yet, nothing happens
- (let* ((all-files (directory (version-n-pathname file "*"))))
- ;; not efficient ... there should be a maximize function that takes a :key arg
- (setq all-files (sort all-files #'> :key #'pathname-pseudoversion))
- (let* ((max-pathname (car all-files))
- (version (if max-pathname
- (1+ (pathname-pseudoversion max-pathname))
- 1))
- (backup-file (version-n-pathname file version)))
- (if rename-old-file
- (rename-file file backup-file)
- (copy-file file backup-file))
- (at-listener-level
- (when (and query-for-reap
- (> (length all-files) *too-many-versions*)
- (y-or-n-p "Delete excess backups of ~A?" file))
- (clean-backups file)))
- backup-file))))
-
- (defun clean-backups (file &key (versions-to-keep 2) (verbose t))
- (let* ((all-files (directory (version-n-pathname file "*"))))
- (setq all-files (sort all-files #'> :key #'pathname-pseudoversion))
- (dolist (file-to-delete (nthcdr (- versions-to-keep 1) all-files))
- (when verbose (format t "~%Deleting ~A" file-to-delete))
- (delete-file file-to-delete)
- )))
-
- ;;; these two functions define the backup pathnames (currently of the form "foo~23.lisp")
- (defun version-n-pathname (file version)
- (make-pathname :name (format nil "~A~~~A" (pathname-name file) version)
- :defaults file))
-
- (defun pathname-pseudoversion (pathname)
- (let* ((string (namestring pathname))
- (number-start (1+ (position #\~ string :from-end t)))
- (number-end (position nil string :start number-start
- :test-not #'(lambda (y x)
- (declare (ignore y))
- (char<= #\0 x #\9)))))
- (read-from-string string nil 0 :start number-start :end number-end)))
-
- ;;; this is risky because the system may define it's own :before method someday
- (defmethod window-save :before ((w window))
- (when *backup-files*
- (window-backup w)))
-
- (defmethod window-backup ((w window))
- (warn "I don't know how to backup windows of class ~A, perhaps you
- would like to write some code!" (class-name (class-of w))))
-
- (defmethod window-backup ((w fred-mixin))
- (let ((file (ccl::stream-filename w)))
- (when file (backup-file file))))
-